use std::path::Path;

use ash::vk;

use crate::VK_LOGP;
use crate::{vulkan::VkContext, VK_CHECK_UNSAFE};

use super::utils_info;

pub fn get_viewport(extent: &vk::Extent2D) -> vk::Viewport {
    vk::Viewport {
        x: 0.0f32,
        y: 0.0f32,
        width: extent.width as f32,
        height: extent.height as f32,
        min_depth: 0.0f32,
        max_depth: 1.0f32
    }
}

pub fn get_scissor(extent: &vk::Extent2D) -> vk::Rect2D {
    vk::Rect2D {
        offset: vk::Offset2D { x: 0, y: 0 },
        extent: *extent
    }
}

pub fn read_shader_code(shader_path: &Path) -> Vec<u8> {
    use std::fs::File;
    use std::io::Read;

    let spv_file = File::open(shader_path)
        .expect(&format!("Failed to find spv file at {:?}", shader_path));
    let bytes_code: Vec<u8> = spv_file.bytes().filter_map(|byte| byte.ok()).collect();

    bytes_code
}

/// 获取shader_path对应的ShaderModule
pub fn load_module(vk_context: &VkContext, shader_path: &Path) -> vk::ShaderModule {
    let code = read_shader_code(shader_path);

    let mut shader_module_ci = utils_info::get_shader_module_ci();
    shader_module_ci.code_size = code.len();
    shader_module_ci.p_code    = code.as_ptr() as *const u32;

    match VK_CHECK_UNSAFE!( vk_context.vk_device.create_shader_module(&shader_module_ci, None) ) {
        Some(inner_value)   => inner_value,
        None                => VK_LOGP!("Failed to create_shader_module") // 这里应该替换成默认的可能更好
    }
}

pub fn get_clear_color(float32: [f32; 4]) -> vk::ClearValue {
    vk::ClearValue {
        color: vk::ClearColorValue { float32: float32 }
    }
}

pub fn get_clear_depth_stencil(depth: f32, stencil: u32) -> vk::ClearValue  {
    vk::ClearValue {
        depth_stencil: vk::ClearDepthStencilValue{ depth: depth, stencil: stencil }
    }
}